//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension EKSAuth {
    // MARK: Enums

    // MARK: Shapes

    public struct AssumeRoleForPodIdentityRequest: AWSEncodableShape {
        /// The name of the cluster for the request.
        public let clusterName: String
        /// The token of the Kubernetes service account for the pod.
        public let token: String

        @inlinable
        public init(clusterName: String, token: String) {
            self.clusterName = clusterName
            self.token = token
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.clusterName, key: "clusterName")
            try container.encode(self.token, forKey: .token)
        }

        public func validate(name: String) throws {
            try self.validate(self.clusterName, name: "clusterName", parent: name, max: 100)
            try self.validate(self.clusterName, name: "clusterName", parent: name, min: 1)
            try self.validate(self.clusterName, name: "clusterName", parent: name, pattern: "^[0-9A-Za-z][A-Za-z0-9\\-_]*$")
            try self.validate(self.token, name: "token", parent: name, min: 1)
            try self.validate(self.token, name: "token", parent: name, pattern: "^[A-Za-z0-9-_=]+\\.[A-Za-z0-9-_=]+\\.[A-Za-z0-9-_=]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case token = "token"
        }
    }

    public struct AssumeRoleForPodIdentityResponse: AWSDecodableShape {
        /// An object with the permanent IAM role identity and the temporary session name. The ARN of the IAM role that the temporary credentials authenticate to. The session name of the temporary session requested to STS. The value is a unique identifier that contains the role ID, a colon (:), and the role session name of the role that is being assumed. The role ID is generated by IAM when the role is created. The role session name part of the value follows this format: eks-clustername-podname-random UUID
        public let assumedRoleUser: AssumedRoleUser
        /// The identity that is allowed to use the credentials. This value is always pods.eks.amazonaws.com.
        public let audience: String
        /// The Amazon Web Services Signature Version 4 type of temporary credentials.
        public let credentials: Credentials
        /// The Amazon Resource Name (ARN) and ID of the EKS Pod Identity association.
        public let podIdentityAssociation: PodIdentityAssociation
        /// The name of the Kubernetes service account inside the cluster to associate the IAM credentials with.
        public let subject: Subject

        @inlinable
        public init(assumedRoleUser: AssumedRoleUser, audience: String, credentials: Credentials, podIdentityAssociation: PodIdentityAssociation, subject: Subject) {
            self.assumedRoleUser = assumedRoleUser
            self.audience = audience
            self.credentials = credentials
            self.podIdentityAssociation = podIdentityAssociation
            self.subject = subject
        }

        private enum CodingKeys: String, CodingKey {
            case assumedRoleUser = "assumedRoleUser"
            case audience = "audience"
            case credentials = "credentials"
            case podIdentityAssociation = "podIdentityAssociation"
            case subject = "subject"
        }
    }

    public struct AssumedRoleUser: AWSDecodableShape {
        /// The ARN of the IAM role that the temporary credentials authenticate to.
        public let arn: String
        /// The session name of the temporary session requested to STS. The value is a unique identifier that contains the role ID, a colon (:), and the role session name of the role that is being assumed. The role ID is generated by IAM when the role is created. The role session name part of the value follows this format: eks-clustername-podname-random UUID
        public let assumeRoleId: String

        @inlinable
        public init(arn: String, assumeRoleId: String) {
            self.arn = arn
            self.assumeRoleId = assumeRoleId
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case assumeRoleId = "assumeRoleId"
        }
    }

    public struct Credentials: AWSDecodableShape {
        /// The access key ID that identifies the temporary security credentials.
        public let accessKeyId: String
        /// The Unix epoch timestamp in seconds when the current credentials expire.
        public let expiration: Date
        /// The secret access key that applications inside the pods use to sign requests.
        public let secretAccessKey: String
        /// The token that applications inside the pods must pass to any service API to use the temporary credentials.
        public let sessionToken: String

        @inlinable
        public init(accessKeyId: String, expiration: Date, secretAccessKey: String, sessionToken: String) {
            self.accessKeyId = accessKeyId
            self.expiration = expiration
            self.secretAccessKey = secretAccessKey
            self.sessionToken = sessionToken
        }

        private enum CodingKeys: String, CodingKey {
            case accessKeyId = "accessKeyId"
            case expiration = "expiration"
            case secretAccessKey = "secretAccessKey"
            case sessionToken = "sessionToken"
        }
    }

    public struct PodIdentityAssociation: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the EKS Pod Identity association.
        public let associationArn: String
        /// The ID of the association.
        public let associationId: String

        @inlinable
        public init(associationArn: String, associationId: String) {
            self.associationArn = associationArn
            self.associationId = associationId
        }

        private enum CodingKeys: String, CodingKey {
            case associationArn = "associationArn"
            case associationId = "associationId"
        }
    }

    public struct Subject: AWSDecodableShape {
        /// The name of the Kubernetes namespace inside the cluster to create the association in. The service account and the pods that use the service account must be in this namespace.
        public let namespace: String
        /// The name of the Kubernetes service account inside the cluster to associate the IAM credentials with.
        public let serviceAccount: String

        @inlinable
        public init(namespace: String, serviceAccount: String) {
            self.namespace = namespace
            self.serviceAccount = serviceAccount
        }

        private enum CodingKeys: String, CodingKey {
            case namespace = "namespace"
            case serviceAccount = "serviceAccount"
        }
    }
}

// MARK: - Errors

/// Error enum for EKSAuth
public struct EKSAuthErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case expiredTokenException = "ExpiredTokenException"
        case internalServerException = "InternalServerException"
        case invalidParameterException = "InvalidParameterException"
        case invalidRequestException = "InvalidRequestException"
        case invalidTokenException = "InvalidTokenException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceUnavailableException = "ServiceUnavailableException"
        case throttlingException = "ThrottlingException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize EKSAuth
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You don't have permissions to perform the requested operation. The IAM principal making the request must have at least one IAM permissions policy attached that grants the required permissions. For more information, see Access management in the IAM User Guide.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// The specified Kubernetes service account token is expired.
    public static var expiredTokenException: Self { .init(.expiredTokenException) }
    /// These errors are usually caused by a server-side issue.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// The specified parameter is invalid. Review the available parameters for the API request.
    public static var invalidParameterException: Self { .init(.invalidParameterException) }
    /// This exception is thrown if the request contains a semantic error. The precise meaning will depend on the API, and will be documented in the error message.
    public static var invalidRequestException: Self { .init(.invalidRequestException) }
    /// The specified Kubernetes service account token is invalid.
    public static var invalidTokenException: Self { .init(.invalidTokenException) }
    /// The specified resource could not be found.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// The service is unavailable. Back off and retry the operation.
    public static var serviceUnavailableException: Self { .init(.serviceUnavailableException) }
    /// The request was denied because your request rate is too high. Reduce the frequency of requests.
    public static var throttlingException: Self { .init(.throttlingException) }
}

extension EKSAuthErrorType: Equatable {
    public static func == (lhs: EKSAuthErrorType, rhs: EKSAuthErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension EKSAuthErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
